
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>

#define BUF_SIZE 100

void error_handling(char* message);
void* recv_message(void* arg);

int main(int argc, char* argv[]) {
    if (argc != 2) {
        printf("Usage: %s <username:password@ip:port>\n", argv[0]);
        exit(1);
    }

    char* token;
    char username[BUF_SIZE];
    char password[BUF_SIZE];
    char ip[BUF_SIZE];
    int port;

    // 解析参数
    token = strtok(argv[1], ":@");
    strcpy(username, token);

    token = strtok(NULL, ":@");
    strcpy(password, token);

    token = strtok(NULL, ":@");
    strcpy(ip, token);

    token = strtok(NULL, ":@");
    port = atoi(token);

    // 创建socket
    int sock = socket(PF_INET, SOCK_STREAM, 0);
    if (sock == -1)
        error_handling("socket() error");

    // 设置服务器地址信息
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(ip);
    serv_addr.sin_port = htons(port);

    // 连接到服务器
    if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
        error_handling("connect() error");

    // 发送认证信息
    char auth_message[BUF_SIZE];
    sprintf(auth_message, "Auth:%s:%s", username, password);
    write(sock, auth_message, strlen(auth_message));

    // 接收认证结果
    char auth_result[BUF_SIZE];
    read(sock, auth_result, sizeof(auth_result));

    if (strcmp(auth_result, "Auth successful") != 0) {
        printf("Authentication failed: %s\n", auth_result);
        close(sock);
        exit(1);
    }

    printf("Authentication successful\n");

    // 创建接收消息的线程
    pthread_t thread;
    if (pthread_create(&thread, NULL, recv_message, (void*)&sock) != 0)
        error_handling("pthread_create() error");

    // 主线程用于发送消息
    while (1) {
        char message[BUF_SIZE];
        printf("Enter message (or 'exit' to quit): ");
        fgets(message, sizeof(message), stdin);

        // 发送消息
        write(sock, message, strlen(message));

        if (strcmp(message, "exit\n") == 0) {
            printf("Exiting...\n");
            break;
        }
    }

    // 等待接收消息的线程结束
    if (pthread_join(thread, NULL) != 0)
        error_handling("pthread_join() error");

    // 关闭socket
    close(sock);

    return 0;
}

void* recv_message(void* arg) {
    int sock = *((int*)arg);
    char message[BUF_SIZE];

    while (1) {
        // 接收对方的消息
        int str_len = read(sock, message, sizeof(message));
        if (str_len <= 0)
            break;

        printf("Received: %s", message);
    }

    return NULL;
}

void error_handling(char* message) {
    fputs(message, stderr);
    fputc('\n', stderr);